home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / ucrasm27.zip / SOURCE.ZIP / INS1STM.ASM < prev    next >
Assembly Source File  |  1992-03-10  |  5KB  |  234 lines

  1.  
  2. ; Need to include "lists.a" in order to get list structure definition.
  3.  
  4.         include    lists.a
  5.         extrn    sl_malloc:far
  6.  
  7.  
  8. wp        equ    <word ptr>        ;I'm a lazy typist
  9.  
  10.  
  11. ; Special case to handle MASM 6.0 vs. all other assemblers:
  12. ; If not MASM 5.1 or MASM 6.0, set the version to 5.00:
  13.  
  14.         ifndef    @version
  15. @version    equ    500
  16.         endif
  17.  
  18.  
  19.  
  20. StdGrp        group    stdlib,stddata
  21. stddata        segment    para public 'sldata'
  22. stddata        ends
  23.  
  24. stdlib        segment    para public 'slcode'
  25.         assume    cs:stdgrp
  26.  
  27.  
  28. ; sl_Insert1stm-    DX:SI points at a block of data bytes.
  29. ;            ES:DI points at a list.
  30. ;            This routine allocates storage for a new node on the
  31. ;            heap, copies the data from DX:SI to the new node,
  32. ;            and then links in the new node to the list.
  33. ;
  34. ;            Returns the carry set if memory allocation error
  35. ;            occurs.
  36. ;
  37. ; Randall Hyde  3/3/92
  38. ;
  39.  
  40.         public    sl_Insert1stm
  41. sl_Insert1stm    proc    far
  42.         pushf
  43.         push    ds
  44.         push    cx
  45.         push    es
  46.         push    di
  47.         cld
  48.  
  49.  
  50.  
  51.         if    @version ge 600
  52.  
  53. ; MASM 6.0 version goes here
  54.  
  55. ; First, allocate storage for the new node:
  56.  
  57.         mov    cx, es:[di].List.ListSize
  58.         push    cx            ;Save for later
  59.         add    cx, size NODE        ;Add in overhead
  60.         call    sl_malloc        ;Go get the memory
  61.         pop    cx            ;Get real length back.
  62.         jc    BadInsert        ;If malloc error
  63.         push    di            ;Save ptr to new NODE.
  64.  
  65. ; Compute offset to actual data area (skipping over list pointers, etc.)
  66.  
  67.         add    di, size Node
  68.  
  69.  
  70.         mov    ds, dx
  71.     rep    movsb                ;Copy the node's data.
  72.         pop    si            ;Get ptr to original node
  73.         mov    cx, es            ;Make ds:si point at node.
  74.         mov    ds, cx
  75.         pop    di            ;Get ptr to list var
  76.         pop    es
  77.         push    es
  78.         push    di
  79.  
  80.         mov    wp es:[di].List.CurrentNode, si
  81.         mov    wp es:[di].List.CurrentNode+2, cx
  82.  
  83. ; Get the pointer to the first item in the list and store its address into the
  84. ; PREV link field of the new node:
  85.  
  86.         cmp    wp es:[di].List.Head+2, 0    ;See if empty list
  87.         jne    ListHasNodes
  88.  
  89. ; If this is an empty list (list is empty if HEAD is NIL), then add the
  90. ; first node to the list.
  91.  
  92.         mov    wp es:[di].List.Tail, si
  93.         mov     wp es:[di].List.Head, si
  94.         mov    wp es:[di].List.Tail+2, ds
  95.         mov    wp es:[di].List.Head+2, ds
  96.         mov    wp [si].Node.Next, 0
  97.         mov    wp [si].Node.Prev, 0
  98.         mov    wp [si].Node.Next+2, 0
  99.         mov    wp [si].Node.Prev+2, 0
  100.         pop    di
  101.         pop    es
  102.         jmp    GoodInsert
  103.  
  104. ;If there were items in the list, perform the insert down here.
  105.  
  106. ListHasNodes:    les    di, es:[di].List.Head        ;Get ptr to first item
  107.         mov    wp ds:[si].Node.Next, di     ;Patch in link
  108.         mov    wp ds:[si].Node.Next+2, es
  109.  
  110. ; Okay, store the new node's address into the PREV field of the first node
  111. ; currently in the list:
  112.  
  113.         mov    wp es:[di].Node.Prev, si    ;Patch in fwd ptr
  114.         mov    wp es:[di].Node.Prev+2, ds
  115.  
  116. ; Set the PREV field of the new node to NIL:
  117.  
  118.         mov    wp ds:[si].Node.Prev, 0        ;Set new node's link
  119.         mov    wp ds:[si].Node.Prev+2, 0    ; to NIL.
  120.  
  121. ; Set the HEAD ptr to the new node
  122.  
  123.         pop    di            ;Retrive ptr to list var.
  124.         pop    es
  125.         mov    wp es:[di].List.Head, si
  126.         mov    wp es:[di].List.Head+2, ds
  127.  
  128.  
  129.  
  130.  
  131.  
  132.         else
  133.  
  134. ; All other assemblers come down here:
  135.  
  136.  
  137. ; First, allocate storage for the new node:
  138.  
  139.         mov    cx, es:[di].ListSize
  140.         push    cx            ;Save for later
  141.         add    cx, size NODE        ;Add in overhead
  142.         call    sl_malloc        ;Go get the memory
  143.         pop    cx            ;Get real length back.
  144.         jc    BadInsert        ;If malloc error
  145.         push    di            ;Save ptr to new NODE.
  146.  
  147. ; Compute offset to actual data area (skipping over list pointers, etc.)
  148.  
  149.         add    di, size Node
  150.  
  151.  
  152.         mov    ds, dx
  153.     rep    movsb                ;Copy the node's data.
  154.         pop    si            ;Get ptr to original node
  155.         mov    cx, es            ;Make ds:si point at node.
  156.         mov    ds, cx
  157.         pop    di            ;Get ptr to list var
  158.         pop    es
  159.         push    es
  160.         push    di
  161.  
  162.         mov    wp es:[di].CurrentNode, si
  163.         mov    wp es:[di+2].CurrentNode, cx
  164.  
  165. ; Get the pointer to the first item in the list and store its address into the
  166. ; PREV link field of the new node:
  167.  
  168.         cmp    wp es:[di].Head+2, 0        ;See if empty list
  169.         jne    ListHasNodes
  170.  
  171. ; If this is an empty list (list is empty if HEAD is NIL), then add the
  172. ; first node to the list.
  173.  
  174.         mov    wp es:[di].Tail, si
  175.         mov     wp es:[di].Head, si
  176.         mov    wp es:[di].Tail+2, ds
  177.         mov    wp es:[di].Head+2, ds
  178.         mov    wp [si].Next, 0
  179.         mov    wp [si].Prev, 0
  180.         mov    wp [si].Next+2, 0
  181.         mov    wp [si].Prev+2, 0
  182.         pop    di
  183.         pop    es
  184.         jmp    GoodInsert
  185.  
  186. ;If there were items in the list, perform the insert down here.
  187.  
  188. ListHasNodes:    les    di, es:[di].Head        ;Get ptr to first item
  189.         mov    wp ds:[si].Next, di         ;Patch in link
  190.         mov    wp ds:[si].Next+2, es
  191.  
  192. ; Okay, store the new node's address into the PREV field of the first node
  193. ; currently in the list:
  194.  
  195.         mov    wp es:[di].Prev, si        ;Patch in fwd ptr
  196.         mov    wp es:[di].Prev+2, ds
  197.  
  198. ; Set the PREV field of the new node to NIL:
  199.  
  200.         mov    wp ds:[si].Prev, 0        ;Set new node's link
  201.         mov    wp ds:[si].Prev+2, 0        ; to NIL.
  202.  
  203. ; Set the HEAD ptr to the new node
  204.  
  205.         pop    di            ;Retrive ptr to list var.
  206.         pop    es
  207.         mov    wp es:[di].Head, si
  208.         mov    wp es:[di].Head+2, ds
  209.  
  210.  
  211.  
  212.         endif
  213.  
  214. ; DANGER WILL ROBINSON! Multiple exit points.  Be wary of these if you
  215. ; change the way things are pushed on the stack.
  216.  
  217. GoodInsert:    pop    cx
  218.         pop    ds
  219.         popf
  220.         clc
  221.         ret
  222.  
  223. BadInsert:    pop    di
  224.         pop    es
  225.         pop    cx
  226.         pop    ds
  227.         popf
  228.         stc
  229.         ret
  230. sl_Insert1stm    endp
  231.  
  232. stdlib        ends
  233.         end
  234.